/**
 * <strong>单例模式是一种创建型设计模式，让你能够保证一个类只有一个实例， 并提供一个访问该实例的全局节点。<br>
 * 单例拥有与全局变量相同的优缺点。 尽管它们非常有用， 但却会破坏代码的模块化特性。<br>
 * 在某些其他上下文中， 你不能使用依赖于单例的类。 你也将必须使用单例类。 绝大多数情况下， 该限制会在创建单元测试时出现。<br>
 * 在 Java 中使用模式</strong><br>
 * <br>
 * 使用示例：许多开发者将单例模式视为一种反模式。 因此它在Java代码中的使用频率正在逐步减少。<br>
 * 尽管如此， Java 核心程序库中仍有相当多的单例示例：<br>
 * {@link java.lang.Runtime#getRuntime()}<br>
 * {@link java.awt.Desktop#getDesktop()}<br>
 * {@link java.lang.System#getSecurityManager()}<br>
 * 识别方法： 单例可以通过返回相同缓存对象的静态构建方法来识别。
 * <br>
 * <strong>单例模式适合应用场景</strong><br>
 * 场景：<br>
 * 如果程序中的某个类对于所有客户端只有一个可用的实例，可以使用单例模式。<br>
 * 解决：<br>
 * 单例模式禁止通过除特殊构建方法以外的任何方式来创建自身类的对象。该方法可以创建一个新对象，但如果该对象已经被创建，则返回已有的对象。<br>
 * <br>
 * 场景：<br>
 * 如果你需要更加严格地控制全局变量，可以使用单例模式。<br>
 * 解决：<br>
 * 单例模式与全局变量不同，它保证类只存在一个实例。除了单例类自己以外，无法通过任何方式替换缓存的实例。<br>
 * 请注意，你可以随时调整限制并设定生成单例实例的数量，只需修改 获取实例 方法， 即 getInstance 中的代码即可实现。<br>
 * <br>
 * <strong>实现方式</strong>
 * <ol>
 *     <li>在类中添加一个私有静态成员变量用于保存单例实例。</li>
 *     <li>声明一个公有静态构建方法用于获取单例实例。</li>
 *     <li>在静态方法中实现"延迟初始化"。该方法会在首次被调用时创建一个新对象，并将其存储在静态成员变量中。此后该方法每次被调用时都返回该实例。</li>
 *     <li>将类的构造函数设为私有。类的静态方法仍能调用构造函数，但是其他对象不能调用。</li>
 *     <li>检查客户端代码，将对单例的构造函数的调用替换为对其静态构建方法的调用。</li>
 * </ol>
 * <br>
 * <strong>单例模式优缺点</strong>
 * 优点：
 * <ol>
 *     <li>你可以保证一个类只有一个实例。</li>
 *     <li>你获得了一个指向该实例的全局访问节点。</li>
 *     <li>仅在首次请求单例对象时对其进行初始化。</li>
 * </ol>
 * 缺点：
 * <ol>
 *     <li>违反了单一职责原则。该模式同时解决了两个问题。</li>
 *     <li>单例模式可能掩盖不良设计，比如程序各组件之间相互了解过多等。</li>
 *     <li>该模式在多线程环境下需要进行特殊处理，避免多个线程多次创建单例对象。</li>
 *     <li>单例的客户端代码单元测试可能会比较困难，因为许多测试框架以基于继承的方式创建模拟对象。由于单例类的构造函数是私有的，而且绝大部分语言无法重写静态方法，所以你需要想出仔细考虑模拟单例的方法。要么干脆不编写测试代码，或者不使用单例模式。</li>
 * </ol>
 * <strong>与其他模式的关系</strong>
 * <ul>
 *     <li>外观类通常可以转换为单例类，因为在大部分情况下一个外观对象就足够了。</li>
 *     <li>如果你能将对象的所有共享状态简化为一个享元对象，那么享元就和单例类似了。但这两个模式有两个根本性的不同。</li>
 *     <ol>
 *         <li>只会有一个单例实体，但是享元类可以有多个实体，各实体的内在状态也可以不同。</li>
 *         <li>单例对象可以是可变的。享元对象是不可变的。</li>
 *     </ol>
 *     <li> 抽象工厂、生成器和原型都可以用单例来实现。</li>
 * </ul>
 */
package com.cg.design.depthdesign.singleton;